package utils.module

import chisel3._
import chisel3.experimental.DataMirror
import utils.logger

object BindingModulePorts {
  def bindModulePorts[T <: Bindable]
  (self: T, source: => RawModule,
   ignoredPorts: Seq[String] = Seq("clock", "reset"),
   shouldFlipped: Seq[String] = Seq()) = {
    DataMirror.modulePorts(source).foreach(item => {
      if (!ignoredPorts.contains(item._1)) {
        logger.debug(s"binding port $item")
        val port = if (item._1.contains("flipped_")) Flipped(item._2.cloneType) else item._2.cloneType
        val portName = item._1
        port.suggestName(portName)
        // bind this port to this module
        self.bindPort(port)
        // connect this port to target module
        try {
          port <> item._2
          // self.bindPort(port)
        } catch {
          case e: Exception =>
            logger.error(s"Connecting port $portName $port error! You can try naming it `flipped_xxx' if 'left and right both are drivers' or similar")
            throw e
        }
      }
    })
  }
}
